package com.fucking.great.context;

import cn.hutool.core.util.ReflectUtil;
import com.fucking.great.context.GreatMain;
import com.fucking.great.context.TxnContext;
import com.fucking.great.context.config.SystemConfigBean;
import com.fucking.great.context.config.TxnConfiger;
import com.fucking.great.context.plun.Plug;
import com.fucking.great.context.plun.PlugFactory;
import com.fucking.great.context.util.SingleUtil;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * 用于测试的基础类，子类只需要继承他就行了。
 */
public abstract class BaseGrateForTest {
    public final TxnContext context;
    protected BaseGrateForTest(String systemName) {
         this.context = initInvoke(systemName, this);
    }

    /**
     * 采用调用本地的，用于调式。
     * 给invoke初始化属性。
     * @param systemName
     * @param invoke
     * @return
     */
    public final static TxnContext initInvoke(String systemName,Object invoke){
        if(invoke == null) throw new NullPointerException("invoke is null.");

        // set
        TxnContext context = TxnContext.getContext();
        context.setSystemName(systemName);

        // get configer
        TxnConfiger txnConfiger = SingleUtil.getBean(TxnConfiger.class);
        SystemConfigBean systemConfigBean = txnConfiger.getSystemConfigBean(systemName);
        /*
            get All userPlun
         */
        Map<String,Object> map = new HashMap<>(); //
        final Map<String, String> config = systemConfigBean.getConfig();
        Collection<PlugFactory> allPlugFactory = txnConfiger.getAllPlugFactory();
        // begin();
        allPlugFactory.forEach( x -> {
            //
            Plug plug = x.initPlug(config);
            Map<String, Object> plugMap = null;
            try {
                plugMap = plug.beginUser();
                map.putAll(plugMap);
            } catch (Exception exception) {
                // igrone
            }
        });

        // 往类中的属性赋值
        Field[] fields = ReflectUtil.getFields(invoke.getClass());
        for (Field field : fields) {
            ReflectUtil.setFieldValue(invoke,field,map.get(field.getName()));
        }
        return context;
    }


    ///
    public TxnContext getContext() {
        return context;
    }
}
